വേഗതയേറിയതും കാര്യക്ഷമവുമായ കോഡ് എഴുതാം. ബാക്ക്ട്രാക്കിംഗ്, ഗ്രീഡി-ലേസി മാച്ചിംഗ്, എഞ്ചിൻ ട്യൂണിംഗ് തുടങ്ങിയ റെഗുലർ എക്സ്പ്രഷൻ ഒപ്റ്റിമൈസേഷനിലെ പ്രധാന ടെക്നിക്കുകൾ പഠിക്കൂ.
റെഗുലർ എക്സ്പ്രഷൻ ഒപ്റ്റിമൈസേഷൻ: റെജെക്സ് പെർഫോമൻസ് ട്യൂണിംഗിലേക്കുള്ള ഒരു ആഴത്തിലുള്ള പഠനം
റെഗുലർ എക്സ്പ്രഷനുകൾ, അഥവാ റെജെക്സ്, ആധുനിക പ്രോഗ്രാമർമാരുടെ ടൂൾകിറ്റിലെ ഒഴിച്ചുകൂടാനാവാത്ത ഒരു ഉപകരണമാണ്. ഉപയോക്താക്കളുടെ ഇൻപുട്ട് സാധൂകരിക്കുന്നതിനും ലോഗ് ഫയലുകൾ പാഴ്സ് ചെയ്യുന്നതിനും സങ്കീർണ്ണമായ സെർച്ച്-ആൻഡ്-റീപ്ലേസ് പ്രവർത്തനങ്ങൾക്കും ഡാറ്റ എക്സ്ട്രാക്ഷനുമൊക്കെ ഇതിൻ്റെ ശക്തിയും വൈവിധ്യവും അനിഷേധ്യമാണ്. എന്നിരുന്നാലും, ഈ ശക്തിക്ക് ഒരു മറഞ്ഞിരിക്കുന്ന വിലയുണ്ട്. മോശമായി എഴുതിയ ഒരു റെജെക്സ് ഒരു നിശബ്ദ പ്രകടന ഘാതകനായി മാറും, ഇത് കാര്യമായ ലേറ്റൻസി ഉണ്ടാക്കുകയും സിപിയു ഉപയോഗം വർദ്ധിപ്പിക്കുകയും ഏറ്റവും മോശം സാഹചര്യങ്ങളിൽ നിങ്ങളുടെ ആപ്ലിക്കേഷനെ നിശ്ചലമാക്കുകയും ചെയ്യും. ഇവിടെയാണ് റെഗുലർ എക്സ്പ്രഷൻ ഒപ്റ്റിമൈസേഷൻ ഒരു 'നല്ല വൈദഗ്ദ്ധ്യം' എന്നതിലുപരി, കരുത്തുറ്റതും വികസിപ്പിക്കാവുന്നതുമായ സോഫ്റ്റ്വെയർ നിർമ്മിക്കുന്നതിന് നിർണായകമാകുന്നത്.
ഈ സമഗ്രമായ ഗൈഡ് നിങ്ങളെ റെജെക്സ് പെർഫോമൻസിൻ്റെ ലോകത്തേക്ക് ആഴത്തിൽ കൊണ്ടുപോകും. ലളിതമെന്ന് തോന്നുന്ന ഒരു പാറ്റേൺ എന്തുകൊണ്ട് വിനാശകരമാംവിധം വേഗത കുറഞ്ഞതാകുന്നു എന്ന് നമ്മൾ പര്യവേക്ഷണം ചെയ്യും, റെജെക്സ് എഞ്ചിനുകളുടെ ആന്തരിക പ്രവർത്തനങ്ങൾ മനസ്സിലാക്കുകയും, ശരിയായതും അതോടൊപ്പം മിന്നൽ വേഗമുള്ളതുമായ റെഗുലർ എക്സ്പ്രഷനുകൾ എഴുതുന്നതിനുള്ള ശക്തമായ ഒരു കൂട്ടം തത്വങ്ങളും സാങ്കേതികതകളും നിങ്ങളെ പഠിപ്പിക്കുകയും ചെയ്യും.
എന്തുകൊണ്ട് എന്ന് മനസ്സിലാക്കാം: ഒരു മോശം റെജെക്സിൻ്റെ വില
ഒപ്റ്റിമൈസേഷൻ ടെക്നിക്കുകളിലേക്ക് കടക്കുന്നതിന് മുമ്പ്, നമ്മൾ പരിഹരിക്കാൻ ശ്രമിക്കുന്ന പ്രശ്നം മനസ്സിലാക്കേണ്ടത് അത്യാവശ്യമാണ്. റെഗുലർ എക്സ്പ്രഷനുകളുമായി ബന്ധപ്പെട്ട ഏറ്റവും ഗുരുതരമായ പ്രകടന പ്രശ്നം കറ്റാസ്ട്രോഫിക് ബാക്ക്ട്രാക്കിംഗ് (Catastrophic Backtracking) എന്നറിയപ്പെടുന്നു, ഇത് ഒരു റെഗുലർ എക്സ്പ്രഷൻ ഡിനയൽ ഓഫ് സർവീസ് (ReDoS) കേടുപാടിലേക്ക് നയിച്ചേക്കാം.
എന്താണ് കറ്റാസ്ട്രോഫിക് ബാക്ക്ട്രാക്കിംഗ്?
ഒരു റെജെക്സ് എഞ്ചിന് ഒരു പൊരുത്തം കണ്ടെത്താൻ (അല്ലെങ്കിൽ പൊരുത്തമൊന്നും സാധ്യമല്ലെന്ന് നിർണ്ണയിക്കാൻ) അസാധാരണമായി ദീർഘനേരം എടുക്കുമ്പോഴാണ് കറ്റാസ്ട്രോഫിക് ബാക്ക്ട്രാക്കിംഗ് സംഭവിക്കുന്നത്. പ്രത്യേക തരം ഇൻപുട്ട് സ്ട്രിംഗുകൾക്കെതിരെ പ്രത്യേക തരം പാറ്റേണുകൾ ഉപയോഗിക്കുമ്പോഴാണ് ഇത് സംഭവിക്കുന്നത്. പാറ്റേൺ തൃപ്തിപ്പെടുത്തുന്നതിനുള്ള സാധ്യമായ എല്ലാ വഴികളും പരീക്ഷിച്ച്, എഞ്ചിൻ പെർമ്യൂട്ടേഷനുകളുടെ ഒരു തലകറങ്ങുന്ന വലയിൽ കുടുങ്ങിപ്പോകുന്നു. ഇൻപുട്ട് സ്ട്രിംഗിൻ്റെ നീളം കൂടുന്നതിനനുസരിച്ച് പടികളുടെ എണ്ണം എക്സ്പോണൻഷ്യലായി വളരുന്നു, ഇത് ഒരു ആപ്ലിക്കേഷൻ ഫ്രീസ് പോലെ തോന്നിക്കുന്നതിലേക്ക് നയിക്കുന്നു.
കേടുപാടുകൾക്ക് സാധ്യതയുള്ള ഈ ക്ലാസിക് ഉദാഹരണം പരിഗണിക്കുക: ^(a+)+$
ഈ പാറ്റേൺ വളരെ ലളിതമായി തോന്നാം: ഒന്നോ അതിലധികമോ 'a' കൾ അടങ്ങിയ ഒരു സ്ട്രിംഗിനായി ഇത് തിരയുന്നു. "a", "aa", "aaaaa" പോലുള്ള സ്ട്രിംഗുകൾക്ക് ഇത് നന്നായി പ്രവർത്തിക്കുന്നു. എന്നാൽ ഏതാണ്ട് പൊരുത്തപ്പെടുകയും എന്നാൽ അവസാനം പരാജയപ്പെടുകയും ചെയ്യുന്ന ഒരു സ്ട്രിംഗിൽ ഇത് പരീക്ഷിക്കുമ്പോഴാണ് പ്രശ്നം ഉണ്ടാകുന്നത്, ഉദാഹരണത്തിന് "aaaaaaaaaaaaaaaaaaaaaaaaaaab".
എന്തുകൊണ്ടാണ് ഇത് ഇത്ര വേഗത കുറഞ്ഞതെന്ന് നോക്കാം:
- പുറത്തെ
(...)+ഉം അകത്തെa+ഉം ഗ്രീഡി ക്വാണ്ടിഫയറുകളാണ്. - അകത്തെ
a+ആദ്യം 27 'a' കളെയും മാച്ച് ചെയ്യുന്നു. - പുറത്തെ
(...)+ഈ ഒരൊറ്റ മാച്ചിൽ തൃപ്തനാകുന്നു. - തുടർന്ന് എഞ്ചിൻ സ്ട്രിംഗിൻ്റെ അവസാനത്തെ സൂചിപ്പിക്കുന്ന
$മാച്ച് ചെയ്യാൻ ശ്രമിക്കുന്നു. അവിടെ ഒരു 'b' ഉള്ളതിനാൽ ഇത് പരാജയപ്പെടുന്നു. - ഇപ്പോൾ, എഞ്ചിൻ ബാക്ക്ട്രാക്ക് ചെയ്യണം. പുറത്തെ ഗ്രൂപ്പ് ഒരു അക്ഷരം ഉപേക്ഷിക്കുന്നു, അതിനാൽ അകത്തെ
a+ഇപ്പോൾ 26 'a' കളെ മാച്ച് ചെയ്യുന്നു, പുറത്തെ ഗ്രൂപ്പിൻ്റെ രണ്ടാമത്തെ ആവർത്തനം അവസാനത്തെ 'a' യെ മാച്ച് ചെയ്യാൻ ശ്രമിക്കുന്നു. ഇതും 'b' യിൽ പരാജയപ്പെടുന്നു. - 'a' കളുടെ സ്ട്രിംഗിനെ അകത്തെ
a+നും പുറത്തെ(...)+നും ഇടയിൽ വിഭജിക്കാനുള്ള സാധ്യമായ എല്ലാ വഴികളും എഞ്ചിൻ ഇപ്പോൾ ശ്രമിക്കും. N 'a' കളുള്ള ഒരു സ്ട്രിംഗിന്, അതിനെ വിഭജിക്കാൻ 2N-1 വഴികളുണ്ട്. സങ്കീർണ്ണത എക്സ്പോണൻഷ്യലാണ്, പ്രോസസ്സിംഗ് സമയം കുതിച്ചുയരുന്നു.
നിരുപദ്രവമെന്ന് തോന്നുന്ന ഈ ഒരൊറ്റ റെജെക്സിന് ഒരു സിപിയു കോറിനെ സെക്കൻഡുകളോ മിനിറ്റുകളോ അതിൽ കൂടുതലോ നേരത്തേക്ക് ലോക്ക് ചെയ്യാൻ കഴിയും, ഇത് മറ്റ് പ്രോസസ്സുകൾക്കോ ഉപയോക്താക്കൾക്കോ ഫലപ്രദമായി സേവനം നിഷേധിക്കുന്നു.
കാര്യത്തിൻ്റെ കാതൽ: റെജെക്സ് എഞ്ചിൻ
റെജെക്സ് ഒപ്റ്റിമൈസ് ചെയ്യുന്നതിന്, എഞ്ചിൻ നിങ്ങളുടെ പാറ്റേൺ എങ്ങനെ പ്രോസസ്സ് ചെയ്യുന്നുവെന്ന് നിങ്ങൾ മനസ്സിലാക്കണം. പ്രധാനമായും രണ്ട് തരം റെജെക്സ് എഞ്ചിനുകളുണ്ട്, അവയുടെ ആന്തരിക പ്രവർത്തനങ്ങൾ പ്രകടന സവിശേഷതകളെ നിർണ്ണയിക്കുന്നു.
DFA (ഡിറ്റർമിനിസ്റ്റിക് ഫൈനൈറ്റ് ഓട്ടോമാറ്റൺ) എഞ്ചിനുകൾ
DFA എഞ്ചിനുകൾ റെജെക്സ് ലോകത്തെ വേഗതയുടെ രാജാക്കന്മാരാണ്. അവ ഇൻപുട്ട് സ്ട്രിംഗ് ഒരൊറ്റ പാസിൽ ഇടത്തുനിന്ന് വലത്തോട്ട്, ഓരോ അക്ഷരമായി പ്രോസസ്സ് ചെയ്യുന്നു. ഏത് സമയത്തും, നിലവിലെ അക്ഷരത്തെ അടിസ്ഥാനമാക്കി അടുത്ത സ്റ്റേറ്റ് എന്തായിരിക്കുമെന്ന് ഒരു DFA എഞ്ചിന് കൃത്യമായി അറിയാം. ഇതിനർത്ഥം അതിന് ഒരിക്കലും ബാക്ക്ട്രാക്ക് ചെയ്യേണ്ടതില്ല. പ്രോസസ്സിംഗ് സമയം ലീനിയറാണ്, ഇത് ഇൻപുട്ട് സ്ട്രിംഗിൻ്റെ നീളത്തിന് നേരിട്ട് ആനുപാതികമാണ്. grep, awk പോലുള്ള പരമ്പരാഗത യുണിക്സ് ടൂളുകൾ DFA അടിസ്ഥാനമാക്കിയുള്ള എഞ്ചിനുകൾ ഉപയോഗിക്കുന്നവയ്ക്ക് ഉദാഹരണങ്ങളാണ്.
ഗുണങ്ങൾ: വളരെ വേഗതയേറിയതും പ്രവചിക്കാവുന്നതുമായ പ്രകടനം. കറ്റാസ്ട്രോഫിക് ബാക്ക്ട്രാക്കിംഗിൽ നിന്ന് സുരക്ഷിതം.
ദോഷങ്ങൾ: പരിമിതമായ ഫീച്ചറുകൾ. ബാക്ക്ട്രാക്കിംഗിനെ ആശ്രയിക്കുന്ന ബാക്ക്റെഫറൻസുകൾ, ലുക്ക് എറൗണ്ടുകൾ, അല്ലെങ്കിൽ ക്യാപ്ചറിംഗ് ഗ്രൂപ്പുകൾ പോലുള്ള വിപുലമായ ഫീച്ചറുകളെ അവ പിന്തുണയ്ക്കുന്നില്ല.
NFA (നോൺ-ഡിറ്റർമിനിസ്റ്റിക് ഫൈനൈറ്റ് ഓട്ടോമാറ്റൺ) എഞ്ചിനുകൾ
പൈത്തൺ, ജാവാസ്ക്രിപ്റ്റ്, ജാവ, C# (.NET), റൂബി, പിഎച്ച്പി, പേൾ തുടങ്ങിയ ആധുനിക പ്രോഗ്രാമിംഗ് ഭാഷകളിൽ ഉപയോഗിക്കുന്ന ഏറ്റവും സാധാരണമായ തരം എഞ്ചിനുകളാണ് NFA. അവ "പാറ്റേൺ-ഡ്രിവൺ" ആണ്, അതായത് എഞ്ചിൻ പാറ്റേൺ പിന്തുടരുകയും സ്ട്രിംഗിലൂടെ മുന്നോട്ട് പോകുകയും ചെയ്യുന്നു. ഒരു അവ്യക്തതയുള്ള സ്ഥാനത്ത് എത്തുമ്പോൾ (ഒരു ആൾട്ടർനേഷൻ | അല്ലെങ്കിൽ ഒരു ക്വാണ്ടിഫയർ *, + പോലുള്ളവ), അത് ഒരു പാത ശ്രമിക്കും. ആ പാത ഒടുവിൽ പരാജയപ്പെട്ടാൽ, അത് അവസാനത്തെ തീരുമാന സ്ഥാനത്തേക്ക് ബാക്ക്ട്രാക്ക് ചെയ്യുകയും ലഭ്യമായ അടുത്ത പാത പരീക്ഷിക്കുകയും ചെയ്യുന്നു.
ഈ ബാക്ക്ട്രാക്കിംഗ് കഴിവാണ് NFA എഞ്ചിനുകളെ ഇത്ര ശക്തവും ഫീച്ചർ സമ്പന്നവുമാക്കുന്നത്, ഇത് ലുക്ക് എറൗണ്ടുകളും ബാക്ക്റെഫറൻസുകളുമുള്ള സങ്കീർണ്ണമായ പാറ്റേണുകൾ സാധ്യമാക്കുന്നു. എന്നിരുന്നാലും, ഇത് തന്നെയാണ് അവയുടെ ഏറ്റവും വലിയ ദൗർബല്യവും, കാരണം കറ്റാസ്ട്രോഫിക് ബാക്ക്ട്രാക്കിംഗ് സാധ്യമാക്കുന്ന സംവിധാനം ഇതാണ്.
ഈ ഗൈഡിൻ്റെ ബാക്കി ഭാഗത്ത്, നമ്മുടെ ഒപ്റ്റിമൈസേഷൻ ടെക്നിക്കുകൾ NFA എഞ്ചിനെ മെരുക്കുന്നതിൽ ശ്രദ്ധ കേന്ദ്രീകരിക്കും, കാരണം ഡെവലപ്പർമാർക്ക് പ്രകടന പ്രശ്നങ്ങൾ കൂടുതലായി നേരിടേണ്ടി വരുന്നത് ഇവിടെയാണ്.
NFA എഞ്ചിനുകൾക്കായുള്ള പ്രധാന ഒപ്റ്റിമൈസേഷൻ തത്വങ്ങൾ
ഇനി, ഉയർന്ന പ്രകടനമുള്ള റെഗുലർ എക്സ്പ്രഷനുകൾ എഴുതാൻ നിങ്ങൾക്ക് ഉപയോഗിക്കാനാകുന്ന പ്രായോഗികവും പ്രവർത്തനക്ഷമവുമായ ടെക്നിക്കുകളിലേക്ക് കടക്കാം.
1. വ്യക്തത പുലർത്തുക: കൃത്യതയുടെ ശക്തി
പ്രകടനത്തെ ബാധിക്കുന്ന ഏറ്റവും സാധാരണമായ ഒരു മോശം രീതി .* പോലുള്ള അമിതമായി സാമാന്യവൽക്കരിച്ച വൈൽഡ്കാർഡുകൾ ഉപയോഗിക്കുന്നതാണ്. ഡോട്ട് . (ഏതാണ്ട്) ഏത് അക്ഷരത്തെയും മാച്ച് ചെയ്യുന്നു, ആസ്റ്ററിസ്ക് * എന്നാൽ "പൂജ്യമോ അതിലധികമോ തവണ" എന്നാണ് അർത്ഥം. ഇവ രണ്ടും ചേരുമ്പോൾ, സ്ട്രിംഗിൻ്റെ ബാക്കി ഭാഗം മുഴുവൻ ഗ്രീഡിയായി എടുക്കാനും, തുടർന്ന് പാറ്റേണിൻ്റെ ബാക്കി ഭാഗം പൊരുത്തപ്പെടുന്നുണ്ടോയെന്ന് കാണാൻ ഓരോ അക്ഷരമായി പിന്നോട്ട് പോകാനും (ബാക്ക്ട്രാക്ക്) എഞ്ചിനോട് നിർദ്ദേശിക്കുന്നു. ഇത് അങ്ങേയറ്റം കാര്യക്ഷമമല്ലാത്ത ഒന്നാണ്.
മോശം ഉദാഹരണം (HTML ടൈറ്റിൽ പാഴ്സ് ചെയ്യുന്നത്):
<title>.*</title>
ഒരു വലിയ HTML ഡോക്യുമെൻ്റിൽ, .* ആദ്യം ഫയലിൻ്റെ അവസാനം വരെ എല്ലാം മാച്ച് ചെയ്യും. തുടർന്ന്, അവസാനത്തെ </title> കണ്ടെത്തുന്നതുവരെ അത് ഓരോ അക്ഷരമായി ബാക്ക്ട്രാക്ക് ചെയ്യും. ഇത് ഒരുപാട് അനാവശ്യ ജോലിയാണ്.
നല്ല ഉദാഹരണം (ഒരു നെഗേറ്റഡ് ക്യാരക്ടർ ക്ലാസ് ഉപയോഗിച്ച്):
<title>[^<]*</title>
ഈ പതിപ്പ് കൂടുതൽ കാര്യക്ഷമമാണ്. നെഗേറ്റഡ് ക്യാരക്ടർ ക്ലാസ് [^<]* എന്നാൽ "ഒരു '<' അല്ലാത്ത ഏത് അക്ഷരത്തെയും പൂജ്യമോ അതിലധികമോ തവണ മാച്ച് ചെയ്യുക" എന്നാണ് അർത്ഥം. എഞ്ചിൻ മുന്നോട്ട് പോകുന്നു, ആദ്യത്തെ '<' കാണുന്നതുവരെ അക്ഷരങ്ങൾ എടുക്കുന്നു. ഇതിന് ഒരിക്കലും ബാക്ക്ട്രാക്ക് ചെയ്യേണ്ടതില്ല. ഇത് നേരിട്ടുള്ള, അവ്യക്തതയില്ലാത്ത ഒരു നിർദ്ദേശമാണ്, ഇത് പ്രകടനത്തിൽ വലിയ നേട്ടമുണ്ടാക്കുന്നു.
2. ഗ്രീഡി vs. ലേസി: ചോദ്യചിഹ്നത്തിൻ്റെ ശക്തി മനസ്സിലാക്കുക
റെജെക്സിലെ ക്വാണ്ടിഫയറുകൾ ഡിഫോൾട്ടായി ഗ്രീഡി (greedy) ആണ്. ഇതിനർത്ഥം, മൊത്തത്തിലുള്ള പാറ്റേൺ പൊരുത്തപ്പെടാൻ അനുവദിക്കുന്നിടത്തോളം സാധ്യമായ ഏറ്റവും കൂടുതൽ ടെക്സ്റ്റ് അവ മാച്ച് ചെയ്യും.
- ഗ്രീഡി:
*,+,?,{n,m}
ഏതൊരു ക്വാണ്ടിഫയറിനും ശേഷം ഒരു ചോദ്യചിഹ്നം ചേർത്തുകൊണ്ട് അതിനെ ലേസി (lazy) ആക്കാം. ഒരു ലേസി ക്വാണ്ടിഫയർ സാധ്യമായ ഏറ്റവും കുറഞ്ഞ ടെക്സ്റ്റ് മാച്ച് ചെയ്യുന്നു.
- ലേസി:
*?,+?,??,{n,m}?
ഉദാഹരണം: ബോൾഡ് ടാഗുകൾ മാച്ച് ചെയ്യുന്നത്
ഇൻപുട്ട് സ്ട്രിംഗ്: <b>First</b> and <b>Second</b>
- ഗ്രീഡി പാറ്റേൺ:
<b>.*</b>
ഇത് മാച്ച് ചെയ്യുന്നത്:<b>First</b> and <b>Second</b>..*എന്നത് അവസാനത്തെ</b>വരെ എല്ലാം ഗ്രീഡിയായി എടുത്തു. - ലേസി പാറ്റേൺ:
<b>.*?</b>
ഇത് ആദ്യ ശ്രമത്തിൽ<b>First</b>നെയും, വീണ്ടും തിരഞ്ഞാൽ<b>Second</b>നെയും മാച്ച് ചെയ്യും..*?പാറ്റേണിൻ്റെ ബാക്കി ഭാഗം (</b>) മാച്ച് ചെയ്യാൻ ആവശ്യമായ ഏറ്റവും കുറഞ്ഞ അക്ഷരങ്ങളെ മാത്രം മാച്ച് ചെയ്തു.
ലേസിനസ് ചില മാച്ചിംഗ് പ്രശ്നങ്ങൾ പരിഹരിക്കുമെങ്കിലും, പ്രകടനത്തിനുള്ള ഒരു ഒറ്റമൂലിയല്ല അത്. ഒരു ലേസി മാച്ചിൻ്റെ ഓരോ ഘട്ടത്തിലും പാറ്റേണിൻ്റെ അടുത്ത ഭാഗം മാച്ച് ആകുന്നുണ്ടോ എന്ന് എഞ്ചിന് പരിശോധിക്കേണ്ടതുണ്ട്. വളരെ വ്യക്തമായ ഒരു പാറ്റേൺ (മുമ്പത്തെ പോയിൻ്റിലെ നെഗേറ്റഡ് ക്യാരക്ടർ ക്ലാസ് പോലെ) പലപ്പോഴും ഒരു ലേസി പാറ്റേണിനേക്കാൾ വേഗതയേറിയതാണ്.
പ്രകടനത്തിൻ്റെ ക്രമം (വേഗതയേറിയത് മുതൽ കുറഞ്ഞത് വരെ):
- വ്യക്തമായ/നെഗേറ്റഡ് ക്യാരക്ടർ ക്ലാസ്:
<b>[^<]*</b> - ലേസി ക്വാണ്ടിഫയർ:
<b>.*?</b> - ധാരാളം ബാക്ക്ട്രാക്കിംഗുള്ള ഗ്രീഡി ക്വാണ്ടിഫയർ:
<b>.*</b>
3. കറ്റാസ്ട്രോഫിക് ബാക്ക്ട്രാക്കിംഗ് ഒഴിവാക്കുക: നെസ്റ്റഡ് ക്വാണ്ടിഫയറുകളെ മെരുക്കുക
ആദ്യത്തെ ഉദാഹരണത്തിൽ കണ്ടതുപോലെ, കറ്റാസ്ട്രോഫിക് ബാക്ക്ട്രാക്കിംഗിൻ്റെ നേരിട്ടുള്ള കാരണം ഒരേ ടെക്സ്റ്റ് മാച്ച് ചെയ്യാൻ കഴിയുന്ന മറ്റൊരു ക്വാണ്ടിഫയർ അടങ്ങുന്ന ഒരു ക്വാണ്ടിഫൈഡ് ഗ്രൂപ്പുള്ള പാറ്റേണാണ്. ഇൻപുട്ട് സ്ട്രിംഗിനെ വിഭജിക്കാൻ ഒന്നിലധികം വഴികളുള്ള ഒരു അവ്യക്തമായ സാഹചര്യത്തെ എഞ്ചിൻ അഭിമുഖീകരിക്കുന്നു.
പ്രശ്നകരമായ പാറ്റേണുകൾ:
(a+)+(a*)*(a|aa)+(a|b)*ഇൻപുട്ട് സ്ട്രിംഗിൽ ധാരാളം 'a'-കളും 'b'-കളും ഉള്ളപ്പോൾ.
പാറ്റേൺ അവ്യക്തതയില്ലാത്തതാക്കുക എന്നതാണ് ഇതിനുള്ള പരിഹാരം. നൽകിയിട്ടുള്ള സ്ട്രിംഗിനെ മാച്ച് ചെയ്യാൻ എഞ്ചിന് ഒരേയൊരു വഴിയേ ഉള്ളൂ എന്ന് നിങ്ങൾ ഉറപ്പാക്കണം.
4. ആറ്റോമിക് ഗ്രൂപ്പുകളും പൊസസ്സീവ് ക്വാണ്ടിഫയറുകളും ഉപയോഗിക്കുക
നിങ്ങളുടെ എക്സ്പ്രഷനുകളിൽ നിന്ന് ബാക്ക്ട്രാക്കിംഗ് ഒഴിവാക്കുന്നതിനുള്ള ഏറ്റവും ശക്തമായ ടെക്നിക്കുകളിൽ ഒന്നാണിത്. ആറ്റോമിക് ഗ്രൂപ്പുകളും പൊസസ്സീവ് ക്വാണ്ടിഫയറുകളും എഞ്ചിനോട് പറയുന്നു: "പാറ്റേണിൻ്റെ ഈ ഭാഗം നിങ്ങൾ മാച്ച് ചെയ്തുകഴിഞ്ഞാൽ, അതിലെ അക്ഷരങ്ങളൊന്നും ഒരിക്കലും തിരികെ നൽകരുത്. ഈ എക്സ്പ്രഷനിലേക്ക് ബാക്ക്ട്രാക്ക് ചെയ്യരുത്."
പൊസസ്സീവ് ക്വാണ്ടിഫയറുകൾ
സാധാരണ ക്വാണ്ടിഫയറിന് ശേഷം ഒരു + ചേർത്താണ് ഒരു പൊസസ്സീവ് ക്വാണ്ടിഫയർ ഉണ്ടാക്കുന്നത് (ഉദാ., *+, ++, ?+, {n,m}+). ജാവ, പിസിആർഇ (പിഎച്ച്പി, ആർ), റൂബി തുടങ്ങിയ എഞ്ചിനുകൾ ഇവയെ പിന്തുണയ്ക്കുന്നു.
ഉദാഹരണം: ഒരു സംഖ്യയ്ക്ക് ശേഷം 'a' മാച്ച് ചെയ്യുന്നത്
ഇൻപുട്ട് സ്ട്രിംഗ്: 12345
- സാധാരണ റെജെക്സ്:
\d+a\d+എന്നത് "12345" നെ മാച്ച് ചെയ്യുന്നു. തുടർന്ന്, എഞ്ചിൻ 'a' യെ മാച്ച് ചെയ്യാൻ ശ്രമിക്കുകയും പരാജയപ്പെടുകയും ചെയ്യുന്നു. അത് ബാക്ക്ട്രാക്ക് ചെയ്യുന്നു, അതിനാൽ\d+ഇപ്പോൾ "1234" നെ മാച്ച് ചെയ്യുന്നു, കൂടാതെ '5' ന് എതിരെ 'a' യെ മാച്ച് ചെയ്യാൻ ശ്രമിക്കുന്നു.\d+അതിൻ്റെ എല്ലാ അക്ഷരങ്ങളും ഉപേക്ഷിക്കുന്നതുവരെ ഇത് തുടരുന്നു. പരാജയപ്പെടാൻ ഒരുപാട് ജോലിയെടുക്കുന്നു. - പൊസസ്സീവ് റെജെക്സ്:
\d++a\d++പൊസസ്സീവായി "12345" നെ മാച്ച് ചെയ്യുന്നു. തുടർന്ന് എഞ്ചിൻ 'a' യെ മാച്ച് ചെയ്യാൻ ശ്രമിക്കുകയും പരാജയപ്പെടുകയും ചെയ്യുന്നു. ക്വാണ്ടിഫയർ പൊസസ്സീവ് ആയിരുന്നതിനാൽ, എഞ്ചിനെ\d++ഭാഗത്തേക്ക് ബാക്ക്ട്രാക്ക് ചെയ്യുന്നതിൽ നിന്ന് വിലക്കിയിരിക്കുന്നു. അത് ഉടനടി പരാജയപ്പെടുന്നു. ഇതിനെ 'വേഗത്തിൽ പരാജയപ്പെടുക' (failing fast) എന്ന് വിളിക്കുന്നു, ഇത് വളരെ കാര്യക്ഷമമാണ്.
ആറ്റോമിക് ഗ്രൂപ്പുകൾ
ആറ്റോമിക് ഗ്രൂപ്പുകൾക്ക് (?>...) എന്ന സിൻ്റാക്സ് ഉണ്ട്, അവ പൊസസ്സീവ് ക്വാണ്ടിഫയറുകളേക്കാൾ വ്യാപകമായി പിന്തുണയ്ക്കപ്പെടുന്നു (ഉദാഹരണത്തിന്, .NET-ലും പൈത്തണിൻ്റെ പുതിയ `regex` മൊഡ്യൂളിലും). അവ പൊസസ്സീവ് ക്വാണ്ടിഫയറുകൾ പോലെ തന്നെ പ്രവർത്തിക്കുന്നു, പക്ഷേ ഒരു മുഴുവൻ ഗ്രൂപ്പിനും ബാധകമാണ്.
(?>\d+)a എന്ന റെജെക്സ് \d++a എന്നതിന് തുല്യമാണ്. യഥാർത്ഥ കറ്റാസ്ട്രോഫിക് ബാക്ക്ട്രാക്കിംഗ് പ്രശ്നം പരിഹരിക്കാൻ നിങ്ങൾക്ക് ആറ്റോമിക് ഗ്രൂപ്പുകൾ ഉപയോഗിക്കാം:
യഥാർത്ഥ പ്രശ്നം: (a+)+
ആറ്റോമിക് പരിഹാരം: ((?>a+))+
ഇപ്പോൾ, അകത്തെ ഗ്രൂപ്പായ (?>a+) ഒരു കൂട്ടം 'a' കളെ മാച്ച് ചെയ്യുമ്പോൾ, പുറത്തെ ഗ്രൂപ്പിന് വീണ്ടും ശ്രമിക്കാനായി അത് അവയെ ഒരിക്കലും തിരികെ നൽകില്ല. ഇത് അവ്യക്തത നീക്കം ചെയ്യുകയും എക്സ്പോണൻഷ്യൽ ബാക്ക്ട്രാക്കിംഗ് തടയുകയും ചെയ്യുന്നു.
5. ആൾട്ടർനേഷനുകളുടെ ക്രമം പ്രധാനമാണ്
ഒരു NFA എഞ്ചിൻ ഒരു ആൾട്ടർനേഷൻ (`|` പൈപ്പ് ഉപയോഗിച്ച്) കാണുമ്പോൾ, അത് ഇടത്തുനിന്ന് വലത്തോട്ട് ബദലുകൾ പരീക്ഷിക്കുന്നു. ഇതിനർത്ഥം നിങ്ങൾ ഏറ്റവും സാധ്യതയുള്ള ബദൽ ആദ്യം സ്ഥാപിക്കണം എന്നാണ്.
ഉദാഹരണം: ഒരു കമാൻഡ് പാഴ്സ് ചെയ്യുന്നത്
നിങ്ങൾ കമാൻഡുകൾ പാഴ്സ് ചെയ്യുകയാണെന്ന് കരുതുക, GET കമാൻഡ് 80% സമയത്തും, SET 15% സമയത്തും, DELETE 5% സമയത്തും ദൃശ്യമാകുന്നുവെന്ന് നിങ്ങൾക്കറിയാം.
കാര്യക്ഷമത കുറഞ്ഞത്: ^(DELETE|SET|GET)
നിങ്ങളുടെ ഇൻപുട്ടുകളുടെ 80% ലും, എഞ്ചിൻ ആദ്യം DELETE മാച്ച് ചെയ്യാൻ ശ്രമിക്കും, പരാജയപ്പെടും, ബാക്ക്ട്രാക്ക് ചെയ്യും, SET മാച്ച് ചെയ്യാൻ ശ്രമിക്കും, പരാജയപ്പെടും, ബാക്ക്ട്രാക്ക് ചെയ്യും, ഒടുവിൽ GET ൽ വിജയിക്കും.
കൂടുതൽ കാര്യക്ഷമമായത്: ^(GET|SET|DELETE)
ഇപ്പോൾ, 80% സമയത്തും, എഞ്ചിന് ആദ്യ ശ്രമത്തിൽ തന്നെ ഒരു മാച്ച് ലഭിക്കുന്നു. ദശലക്ഷക്കണക്കിന് ലൈനുകൾ പ്രോസസ്സ് ചെയ്യുമ്പോൾ ഈ ചെറിയ മാറ്റം ശ്രദ്ധേയമായ സ്വാധീനം ചെലുത്തും.
6. ക്യാപ്ചർ ആവശ്യമില്ലാത്തപ്പോൾ നോൺ-ക്യാപ്ചറിംഗ് ഗ്രൂപ്പുകൾ ഉപയോഗിക്കുക
റെജെക്സിലെ പരാൻതീസിസുകൾ (...) രണ്ട് കാര്യങ്ങൾ ചെയ്യുന്നു: അവ ഒരു സബ്-പാറ്റേൺ ഗ്രൂപ്പ് ചെയ്യുകയും ആ സബ്-പാറ്റേണുമായി പൊരുത്തപ്പെടുന്ന ടെക്സ്റ്റ് ക്യാപ്ചർ ചെയ്യുകയും ചെയ്യുന്നു. ഈ ക്യാപ്ചർ ചെയ്ത ടെക്സ്റ്റ് പിന്നീട് ഉപയോഗിക്കുന്നതിനായി മെമ്മറിയിൽ സൂക്ഷിക്കുന്നു (ഉദാഹരണത്തിന്, \1 പോലുള്ള ബാക്ക്റെഫറൻസുകളിലോ കോഡ് വഴി എക്സ്ട്രാക്റ്റുചെയ്യുന്നതിനോ). ഈ സംഭരണത്തിന് ചെറുതാണെങ്കിലും അളക്കാവുന്ന ഒരു ഓവർഹെഡ് ഉണ്ട്.
നിങ്ങൾക്ക് ഗ്രൂപ്പിംഗ് മാത്രം ആവശ്യമുള്ളപ്പോൾ, എന്നാൽ ടെക്സ്റ്റ് ക്യാപ്ചർ ചെയ്യേണ്ടതില്ലാത്തപ്പോൾ, ഒരു നോൺ-ക്യാപ്ചറിംഗ് ഗ്രൂപ്പ് ഉപയോഗിക്കുക: (?:...).
ക്യാപ്ചറിംഗ്: (https?|ftp)://([^/]+)
ഇത് "http" യെയും ഡൊമെയ്ൻ നാമത്തെയും വെവ്വേറെ ക്യാപ്ചർ ചെയ്യുന്നു.
നോൺ-ക്യാപ്ചറിംഗ്: (?:https?|ftp)://([^/]+)
ഇവിടെ, നമ്മൾ https?|ftp നെ ഗ്രൂപ്പ് ചെയ്യുന്നു, അതിനാൽ :// ശരിയായി പ്രയോഗിക്കുന്നു, പക്ഷേ നമ്മൾ മാച്ച് ചെയ്ത പ്രോട്ടോക്കോൾ സംഭരിക്കുന്നില്ല. ഡൊമെയ്ൻ നാമം (ഗ്രൂപ്പ് 1-ൽ ഉള്ളത്) എക്സ്ട്രാക്റ്റുചെയ്യുന്നതിൽ മാത്രം നിങ്ങൾക്ക് താൽപ്പര്യമുണ്ടെങ്കിൽ ഇത് അല്പം കൂടുതൽ കാര്യക്ഷമമാണ്.
വിപുലമായ ടെക്നിക്കുകളും എഞ്ചിൻ-നിർദ്ദിഷ്ട നുറുങ്ങുകളും
ലുക്ക് എറൗണ്ടുകൾ: ശക്തമാണ്, പക്ഷേ ശ്രദ്ധയോടെ ഉപയോഗിക്കുക
ലുക്ക് എറൗണ്ടുകൾ (ലുക്ക് എഹെഡ് (?=...), (?!...), ലുക്ക് ബിഹൈൻഡ് (?<=...), (?) സീറോ-വിഡ്ത്ത് അസെർഷനുകളാണ്. അവ യഥാർത്ഥത്തിൽ അക്ഷരങ്ങളൊന്നും ഉപയോഗിക്കാതെ ഒരു വ്യവസ്ഥ പരിശോധിക്കുന്നു. സന്ദർഭം സാധൂകരിക്കുന്നതിന് ഇത് വളരെ കാര്യക്ഷമമാകും.
ഉദാഹരണം: പാസ്വേഡ് സാധൂകരണം
ഒരു അക്കം അടങ്ങിയിരിക്കേണ്ട പാസ്വേഡ് സാധൂകരിക്കുന്നതിനുള്ള ഒരു റെജെക്സ്:
^(?=.*\d).{8,}$
ഇത് വളരെ കാര്യക്ഷമമാണ്. ലുക്ക് എഹെഡ് (?=.*\d) ഒരു അക്കം നിലവിലുണ്ടെന്ന് ഉറപ്പാക്കാൻ മുന്നോട്ട് സ്കാൻ ചെയ്യുന്നു, തുടർന്ന് കഴ്സർ തുടക്കത്തിലേക്ക് പുനഃസ്ഥാപിക്കുന്നു. പാറ്റേണിൻ്റെ പ്രധാന ഭാഗമായ .{8,} ന് 8 ഓ അതിലധികമോ അക്ഷരങ്ങളെ മാച്ച് ചെയ്താൽ മതി. ഇത് കൂടുതൽ സങ്കീർണ്ണമായ, ഒറ്റ-പാത പാറ്റേണിനേക്കാൾ പലപ്പോഴും മികച്ചതാണ്.
പ്രീ-കമ്പ്യൂട്ടേഷനും കംപൈലേഷനും
മിക്ക പ്രോഗ്രാമിംഗ് ഭാഷകളും ഒരു റെഗുലർ എക്സ്പ്രഷൻ "കംപൈൽ" ചെയ്യാൻ ഒരു വഴി വാഗ്ദാനം ചെയ്യുന്നു. ഇതിനർത്ഥം എഞ്ചിൻ പാറ്റേൺ സ്ട്രിംഗ് ഒരിക്കൽ പാഴ്സ് ചെയ്യുകയും ഒരു ഒപ്റ്റിമൈസ് ചെയ്ത ആന്തരിക രൂപം സൃഷ്ടിക്കുകയും ചെയ്യുന്നു. നിങ്ങൾ ഒരേ റെജെക്സ് ഒന്നിലധികം തവണ ഉപയോഗിക്കുകയാണെങ്കിൽ (ഉദാഹരണത്തിന്, ഒരു ലൂപ്പിനുള്ളിൽ), നിങ്ങൾ എല്ലായ്പ്പോഴും അത് ലൂപ്പിന് പുറത്ത് ഒരിക്കൽ കംപൈൽ ചെയ്യണം.
പൈത്തൺ ഉദാഹരണം:
import re
# റെജെക്സ് ഒരിക്കൽ കംപൈൽ ചെയ്യുക
log_pattern = re.compile(r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})')
for line in log_file:
# കംപൈൽ ചെയ്ത ഒബ്ജക്റ്റ് ഉപയോഗിക്കുക
match = log_pattern.search(line)
if match:
print(match.group(1))
ഇത് ചെയ്യാതിരിക്കുന്നത് ഓരോ ആവർത്തനത്തിലും സ്ട്രിംഗ് പാറ്റേൺ വീണ്ടും പാഴ്സ് ചെയ്യാൻ എഞ്ചിനെ നിർബന്ധിക്കുന്നു, ഇത് സിപിയു സൈക്കിളുകളുടെ കാര്യമായ പാഴാക്കലാണ്.
റെജെക്സ് പ്രൊഫൈലിംഗിനും ഡീബഗ്ഗിംഗിനുമുള്ള പ്രായോഗിക ഉപകരണങ്ങൾ
സിദ്ധാന്തം നല്ലതാണ്, പക്ഷേ കണ്ടാൽ മാത്രമേ വിശ്വസിക്കൂ. പ്രകടനം മനസ്സിലാക്കുന്നതിനുള്ള വിലമതിക്കാനാവാത്ത ഉപകരണങ്ങളാണ് ആധുനിക ഓൺലൈൻ റെജെക്സ് ടെസ്റ്ററുകൾ.
regex101.com പോലുള്ള വെബ്സൈറ്റുകൾ ഒരു "റെജെക്സ് ഡീബഗ്ഗർ" അല്ലെങ്കിൽ "ഘട്ടം ഘട്ടമായുള്ള വിശദീകരണം" ഫീച്ചർ നൽകുന്നു. നിങ്ങളുടെ റെജെക്സും ഒരു ടെസ്റ്റ് സ്ട്രിംഗും അവിടെ നൽകിയാൽ, NFA എഞ്ചിൻ സ്ട്രിംഗ് എങ്ങനെ പ്രോസസ്സ് ചെയ്യുന്നു എന്നതിൻ്റെ ഘട്ടം ഘട്ടമായുള്ള ഒരു ട്രേസ് അത് നൽകും. ഓരോ മാച്ച് ശ്രമവും, പരാജയവും, ബാക്ക്ട്രാക്കും ഇത് വ്യക്തമായി കാണിക്കുന്നു. നിങ്ങളുടെ റെജെക്സ് എന്തുകൊണ്ട് വേഗത കുറഞ്ഞതാണെന്ന് ദൃശ്യവൽക്കരിക്കാനും നമ്മൾ ചർച്ച ചെയ്ത ഒപ്റ്റിമൈസേഷനുകളുടെ സ്വാധീനം പരീക്ഷിക്കാനുമുള്ള ഏറ്റവും നല്ല മാർഗ്ഗമാണിത്.
റെജെക്സ് ഒപ്റ്റിമൈസേഷനായുള്ള ഒരു പ്രായോഗിക ചെക്ക്ലിസ്റ്റ്
സങ്കീർണ്ണമായ ഒരു റെജെക്സ് ഉപയോഗിക്കുന്നതിന് മുമ്പ്, ഈ മാനസിക ചെക്ക്ലിസ്റ്റിലൂടെ കടന്നുപോകുക:
- വ്യക്തത: കൂടുതൽ വ്യക്തമായ
[^"\r\n]*പോലുള്ള ഒരു നെഗേറ്റഡ് ക്യാരക്ടർ ക്ലാസ് വേഗതയേറിയതും സുരക്ഷിതവുമാകുന്നിടത്ത് ഞാൻ ഒരു ലേസി.*?യോ ഗ്രീഡി.*യോ ഉപയോഗിച്ചിട്ടുണ്ടോ? - ബാക്ക്ട്രാക്കിംഗ്: എനിക്ക്
(a+)+പോലുള്ള നെസ്റ്റഡ് ക്വാണ്ടിഫയറുകൾ ഉണ്ടോ? ചില ഇൻപുട്ടുകളിൽ കറ്റാസ്ട്രോഫിക് ബാക്ക്ട്രാക്കിംഗിലേക്ക് നയിച്ചേക്കാവുന്ന അവ്യക്തതയുണ്ടോ? - പൊസസ്സീവ്നെസ്: പുനർമൂല്യനിർണ്ണയം ചെയ്യരുതെന്ന് എനിക്കറിയാവുന്ന ഒരു സബ്-പാറ്റേണിലേക്ക് ബാക്ക്ട്രാക്ക് ചെയ്യുന്നത് തടയാൻ എനിക്ക് ഒരു ആറ്റോമിക് ഗ്രൂപ്പ്
(?>...)അല്ലെങ്കിൽ ഒരു പൊസസ്സീവ് ക്വാണ്ടിഫയർ*+ഉപയോഗിക്കാൻ കഴിയുമോ? - ആൾട്ടർനേഷനുകൾ: എൻ്റെ
(a|b|c)ആൾട്ടർനേഷനുകളിൽ, ഏറ്റവും സാധാരണമായ ബദൽ ആദ്യമാണോ ലിസ്റ്റ് ചെയ്തിരിക്കുന്നത്? - ക്യാപ്ചറിംഗ്: എൻ്റെ എല്ലാ ക്യാപ്ചറിംഗ് ഗ്രൂപ്പുകളും ആവശ്യമുണ്ടോ? ഓവർഹെഡ് കുറയ്ക്കുന്നതിന് ചിലതിനെ നോൺ-ക്യാപ്ചറിംഗ് ഗ്രൂപ്പുകളാക്കി
(?:...)മാറ്റാൻ കഴിയുമോ? - കംപൈലേഷൻ: ഞാൻ ഈ റെജെക്സ് ഒരു ലൂപ്പിൽ ഉപയോഗിക്കുകയാണെങ്കിൽ, ഞാൻ അത് മുൻകൂട്ടി കംപൈൽ ചെയ്യുന്നുണ്ടോ?
കേസ് സ്റ്റഡി: ഒരു ലോഗ് പാർസർ ഒപ്റ്റിമൈസ് ചെയ്യുന്നത്
നമുക്ക് ഇതെല്ലാം ഒരുമിച്ച് ചേർക്കാം. നമ്മൾ ഒരു സാധാരണ വെബ് സെർവർ ലോഗ് ലൈൻ പാഴ്സ് ചെയ്യുകയാണെന്ന് സങ്കൽപ്പിക്കുക.
ലോഗ് ലൈൻ: 127.0.0.1 - - [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326
മുമ്പ് (വേഗത കുറഞ്ഞ റെജെക്സ്):
^(\S+) (\S+) (\S+) \[(.*)\] "(.*)" (\d+) (\d+)$
ഈ പാറ്റേൺ പ്രവർത്തനക്ഷമമാണെങ്കിലും കാര്യക്ഷമമല്ല. തീയതിക്കും അഭ്യർത്ഥന സ്ട്രിംഗിനുമുള്ള (.*) കാര്യമായി ബാക്ക്ട്രാക്ക് ചെയ്യും, പ്രത്യേകിച്ചും തെറ്റായ ഫോർമാറ്റിലുള്ള ലോഗ് ലൈനുകൾ ഉണ്ടെങ്കിൽ.
ശേഷം (ഒപ്റ്റിമൈസ് ചെയ്ത റെജെക്സ്):
^(\S+) (\S+) (\S+) \[[^\]]+\] "(?:GET|POST|HEAD) ([^ "]+) HTTP/[\d.]+" (\d{3}) (\d+)$
മെച്ചപ്പെടുത്തലുകൾ വിശദീകരിച്ചു:
\[(.*)\]എന്നത്\[[^\]]+\]ആയി മാറി. ഞങ്ങൾ സാമാന്യവൽക്കരിച്ച, ബാക്ക്ട്രാക്കിംഗ്.*ന് പകരം ക്ലോസിംഗ് ബ്രാക്കറ്റ് ഒഴികെ മറ്റെന്തിനെയും മാച്ച് ചെയ്യുന്ന വളരെ വ്യക്തമായ ഒരു നെഗേറ്റഡ് ക്യാരക്ടർ ക്ലാസ് ഉപയോഗിച്ചു. ബാക്ക്ട്രാക്കിംഗ് ആവശ്യമില്ല."(.*)"എന്നത്"(?:GET|POST|HEAD) ([^ "]+) HTTP/[\d.]+"ആയി മാറി. ഇത് ഒരു വലിയ മെച്ചപ്പെടുത്തലാണ്.- നമ്മൾ പ്രതീക്ഷിക്കുന്ന HTTP രീതികളെക്കുറിച്ച് ഒരു നോൺ-ക്യാപ്ചറിംഗ് ഗ്രൂപ്പ് ഉപയോഗിച്ച് ഞങ്ങൾ വ്യക്തമാക്കുന്നു.
- ഒരു സാമാന്യ വൈൽഡ്കാർഡിന് പകരം
[^ "]+(സ്പേസോ ഉദ്ധരണിയോ അല്ലാത്ത ഒന്നോ അതിലധികമോ അക്ഷരങ്ങൾ) ഉപയോഗിച്ച് ഞങ്ങൾ URL പാത്ത് മാച്ച് ചെയ്യുന്നു. - HTTP പ്രോട്ടോക്കോൾ ഫോർമാറ്റ് ഞങ്ങൾ വ്യക്തമാക്കുന്നു.
- സ്റ്റാറ്റസ് കോഡിനായുള്ള
(\d+)എന്നത്(\d{3})ആയി കർശനമാക്കി, കാരണം HTTP സ്റ്റാറ്റസ് കോഡുകൾക്ക് എല്ലായ്പ്പോഴും മൂന്ന് അക്കങ്ങളുണ്ട്.
'ശേഷം' ഉള്ള പതിപ്പ് നാടകീയമായി വേഗതയേറിയതും ReDoS ആക്രമണങ്ങളിൽ നിന്ന് സുരക്ഷിതവുമാണെന്ന് മാത്രമല്ല, ലോഗ് ലൈനിൻ്റെ ഫോർമാറ്റ് കൂടുതൽ കർശനമായി സാധൂകരിക്കുന്നതിനാൽ ഇത് കൂടുതൽ കരുത്തുറ്റതുമാണ്.
ഉപസംഹാരം
റെഗുലർ എക്സ്പ്രഷനുകൾ ഇരുതല മൂർച്ചയുള്ള വാളാണ്. ശ്രദ്ധയോടെയും അറിവോടെയും ഉപയോഗിക്കുമ്പോൾ, സങ്കീർണ്ണമായ ടെക്സ്റ്റ് പ്രോസസ്സിംഗ് പ്രശ്നങ്ങൾക്ക് അവ ഒരു മികച്ച പരിഹാരമാണ്. അശ്രദ്ധമായി ഉപയോഗിച്ചാൽ, അവ ഒരു പ്രകടന ദുഃസ്വപ്നമായി മാറും. NFA എഞ്ചിൻ്റെ ബാക്ക്ട്രാക്കിംഗ് സംവിധാനത്തെക്കുറിച്ച് ബോധവാന്മാരായിരിക്കുകയും, സാധ്യമാകുമ്പോഴെല്ലാം എഞ്ചിനെ ഒരൊറ്റ, അവ്യക്തതയില്ലാത്ത പാതയിലൂടെ നയിക്കുന്ന പാറ്റേണുകൾ എഴുതുകയുമാണ് പ്രധാന പാഠം.
വ്യക്തത പുലർത്തുന്നതിലൂടെയും, ഗ്രീഡിനസ്സിൻ്റെയും ലേസിനസ്സിൻ്റെയും ഗുണദോഷങ്ങൾ മനസ്സിലാക്കുന്നതിലൂടെയും, ആറ്റോമിക് ഗ്രൂപ്പുകൾ ഉപയോഗിച്ച് അവ്യക്തത ഇല്ലാതാക്കുന്നതിലൂടെയും, നിങ്ങളുടെ പാറ്റേണുകൾ പരീക്ഷിക്കുന്നതിന് ശരിയായ ഉപകരണങ്ങൾ ഉപയോഗിക്കുന്നതിലൂടെയും, നിങ്ങളുടെ റെഗുലർ എക്സ്പ്രഷനുകളെ ഒരു സാധ്യതയുള്ള ബാധ്യതയിൽ നിന്ന് നിങ്ങളുടെ കോഡിലെ ശക്തവും കാര്യക്ഷമവുമായ ഒരു മുതൽക്കൂട്ടാക്കി മാറ്റാൻ കഴിയും. ഇന്ന് തന്നെ നിങ്ങളുടെ റെജെക്സ് പ്രൊഫൈൽ ചെയ്യാൻ തുടങ്ങൂ, വേഗതയേറിയതും കൂടുതൽ വിശ്വസനീയവുമായ ഒരു ആപ്ലിക്കേഷൻ സ്വന്തമാക്കൂ.